-----------Stickybear Numbers----------
A 4am crack                  2017-04-18
---------------------------------------

Name: Stickybear Numbers
Version: 18-JAN-1989 (based on ProDOS
  disk catalog)
Genre: educational
Year: 1989
Credits: programming by Steve & Janie
  Worthington, pictures by Richard
  Hefter
Publisher: Optimum Resource
Platform: Apple ][+ or later (64K)
Media: single-sided 5.25-inch floppy
OS:
Previous cracks: none

                   ~

               Chapter 0
 In Which Various Automated Tools Fail
          In Interesting Ways


COPYA
  read error on second pass

Locksmith Fast Disk Backup
  unable to read T07,S0F
  copy boots ProDOS then hangs with the
  drive motor off

EDD 4 bit copy (no sync, no count)
  works

Copy ][+
  "Disk Map" shows that T07,S0F is
  marked as used but is suspiciously
  unused by any actual files

                 --v--

DISK MAP                SLOT 6  DRIVE 1
/SBNUMBERS/NUMBERS.DAT

   TRACK           1               2
   0123456789ABCDEF0123456789ABCDEF012

S0 .......***********************.....
EE .......***********************.....
CD .......***********************.....
TC .......***********************.....
OB .......***********************.....
RA .......***********************.....
 9 .......***********************.....
 8 .......***********************.....
 7 .......***********************.....
 6 .......***********************.....
 5 ......************************.....
 4 ......************************.....
 3 ......************************.....
 2 ......************************.....
 1 ......*.*********************......
 F ......*.*********************......

   USE ARROW KEYS TO MAP OTHER FILES

                 --^--

Why didn't COPYA work?
  intentionally corrupted sector on
  track 7

Why didn't Locksmith FDB work?
  ditto

EDD worked. What does that tell us?
  No half or quarter tracks, because I
  didn't even try to copy those. There
  is definitely a run-time protection
  check of some kind, but it's probably
  just checking that that one sector on
  track 7 is unreadable. Since ProDOS
  loads, the check code is probably in
  the first .SYSTEM file.

Next steps:

  1. Search disk for common elements of
     a run-time protection check
  2. If that fails, trace the boot
  3. If that fails, I dunno, go feed
     the ducks or something

                   ~

               Chapter 1
        In Which We Get Lucky,
     To The Detriment Of The Ducks


On the theory that some code on disk is
trying to access T07,S0F, and thus
noticing if it's unexpectedly readable,
let's enumerate some of the ways that
could happen:

- Reading a file that is mapped to the
  unreadable sector. Copy II+ "disk
  map" shows there are no files mapped
  to T07,S0F, so let's rule that out.

- Manually seeking to the track and
  looking for a nibble sequence. There
  is no explicit support for "seeking
  to a particular track" unless you're
  calling ProDOS internals. Without
  calling into ProDOS, this technique
  would require low-level disk access
  (turning on the drive and hitting the
  right stepper motors and whatnot).
  Here are some possibilities:

  "BD 89 C0" (LDA $C089,X)   ; drive on
  "AD E9 C0" (LDA $C0E9)     ; drive on
  "BD 80 C0" (LDA $C080,X)   ; stepper

  Searching for these common opcodes
  yield no suspicious-looking results.
  (There are matches inside legitimate
  RWTS code in the PRODOS system.)

- Issuing a ProDOS MLI "raw block read"
  and checking the return code. This is
  a popular technique under ProDOS,
  partly because it can be adapted to
  work on 3.5-inch and 5.25-inch disks.
  A sector search for "20 00 BF" (a JSR
  to the standard ProDOS MLI entry
  point) yields two results:

                 --v--

------------- DISK SEARCH -------------

$00/$0F-$38   $02/$0D-$06


             PRESS [RETURN]

                 --^--

T02,S0D is an expected part of the
PRODOS file. That leaves T00,S0F.

Copy II Plus says that's part of the
file LOADER.SYSTEM, which would fit my
theory that there's a runtime check in
the first .SYSTEM file.

Switching over to the BASIC prompt, I
can load up LOADER.SYSTEM and see what
is going on.

                   ~

               Chapter 1
      In Which It All Comes Down
              To One Byte


[S7,D1=ProDOS hard drive, "A4AMCRACK"]
[S6,D1=non-working copy]

]PR#7
...

]CAT,S6,D1

/SBNUMBERS

 NAME           TYPE  BLOCKS  MODIFIED

 LOADER.SYSTEM   SYS       3  11-JAN-89
 SAY             BIN       5  23-JAN-87
 PRODOS          SYS      32  17-APR-87
 NUMBERS.WRD     TXT       6  20-DEC-88
 NUMBERS.DAT     BIN     185  18-JAN-89
 NUMBERS         BIN      12  18-JAN-89
 ECHO            BIN       1   9-JAN-89
 FINDER.DATA     $C9       1   3-FEB-89

BLOCKS FREE:   27     BLOCKS USED:  253

]PREFIX /SBNUMBERS
]BLOAD LOADER.SYSTEM,A$2000,TSYS
]CALL-151

*2000L

2000-   A9 00       LDA   #$00
2002-   85 50       STA   $50
2004-   A9 02       LDA   #$02

; machine identification (not shown)
2006-   20 EE 21    JSR   $21EE

; more machine identification
2009-   AD B3 FB    LDA   $FBB3
200C-   C9 06       CMP   #$06
200E-   D0 19       BNE   $2029
2010-   AD C0 FB    LDA   $FBC0
2013-   F0 0C       BEQ   $2021
2015-   AD 98 BF    LDA   $BF98
2018-   29 30       AND   #$30
201A-   C9 30       CMP   #$30
201C-   D0 0B       BNE   $2029
201E-   4C 26 20    JMP   $2026

; even more machine ID (not shown, but
; it seems to be looking for some sort
; of peripheral card in slot 2 -- maybe
; a voice card?)
2021-   20 C9 20    JSR   $20C9
2024-   90 03       BCC   $2029
2026-   20 3F 21    JSR   $213F

; well this part is very interesting
2029-   20 38 21    JSR   $2138
202C-   D0 03       BNE   $2031

; an infinite loop!
202E-   4C 2E 20    JMP   $202E

Now we're getting somewhere. Legitimate
code does not suddenly fall into an
infinite loop.

*2138L

; call ProDOS MLI
2138-   20 00 BF    JSR   $BF00
213B-  [80]       ; READ_BLOCK command
213C-  [78 20]    ; MLI parameter table
213E-   60          RTS

That's it. A raw block read command.
And what are we reading? I'm glad you
asked.

*2078.

      +--- MLI parameter count
      |  +--- slot/drive (S6,D1)
      |  |  +--- address ($BB00)
      |  |  |     +--- block number
      v  v  v     v
2078- 03 60 00 BB 3F 00

Block #$003F would put us smack dab
onto... track $07, sector $0F.

Returning to the caller, all we're
doing is looking at the return code in
the accumulator after the MLI call:

202C-   D0 03       BNE   $2031
202E-   4C 2E 20    JMP   $202E
...

If the accumulator is 0, that means the
READ_BLOCK call succeeded. Anything
else is an error code. But the caller
doesn't even care what the error is, as
long as there is one.

That gives me an idea.

A simple trick I've used on other disks
is to change the MLI command from
READ_BLOCK to CLOSE_ALL_FILES. Why?
Because the CLOSE_ALL_FILES command
takes a different number of parameters
in the MLI parameter table (1 instead
of 3), so the call always fails with
return code #$04 ("incorrect parameter
count"). And that's the behavior we
want! We want the MLI call to always
fail! Failure is success!

T00,S0F,$3B: 80 -> CC

]PR#6
...works, and it is glorious...

The other advantage of this patch is
that you can copy all the files on the
disk onto a directory on your ProDOS
hard drive (you DO have a ProDOS hard
drive, don't you?) and the program will
work without modification. It doesn't
even do any weird raw block reads of
your hard drive, since we just changed
the weird block read to a harmless MLI
call that always fails.

Quod erat liberandum.

---------------------------------------
A 4am crack                    No. 1147
------------------EOF------------------
